from typing import List, Dict, Any
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session

from app.core.database.connection import get_database
from app.domains.device.services import DeviceService
from app.domains.device.schemas import (
    DeviceCreate, DeviceUpdate, DeviceResponse, DeviceDetailResponse,
    DeviceListQuery, DeviceStatusUpdate, DeviceControlRequest,
    SensorDataResponse, SensorDataQuery, DeviceBatchOperation
)
from app.shared.schemas.response import success_response, paginated_response, error_response
from app.shared.exceptions.base import ValidationException, BusinessException, NotFoundException
from app.shared.constants.status_codes import BusinessCode
from app.api.dependencies import get_current_user, require_roles, check_resource_permission, ResourcePermission
from app.shared.constants.enums import UserRole
import logging

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/devices", tags=["设备管理"])


@router.post("", response_model=dict, summary="创建设备")
async def create_device(
    device_data: DeviceCreate,
    current_user: dict = Depends(check_resource_permission(
        ResourcePermission.can_manage_devices, "无权限创建设备"
    )),
    db: Session = Depends(get_database)
):
    """
    创建设备（管理员和经理可操作）
    
    - **device_code**: 设备编码（唯一）
    - **device_name**: 设备名称
    - **device_type**: 设备类型
    - **location_name**: 位置名称（可选）
    - **latitude**: 纬度（可选）
    - **longitude**: 经度（可选）
    """
    try:
        device_service = DeviceService(db)
        device = device_service.create_device(device_data)
        
        logger.info(f"✅ 设备创建成功: {device.device_code} by {current_user['username']}")
        
        return success_response(
            data=DeviceResponse.from_orm(device).dict(),
            message="设备创建成功"
        )
        
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except Exception as e:
        logger.error(f"❌ 创建设备异常: {e}")
        return error_response(
            message="创建设备失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.get("", response_model=dict, summary="获取设备列表")
async def get_device_list(
    query: DeviceListQuery = Depends(),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    获取设备列表（所有用户都可查看）
    
    - **page**: 页码（默认1）
    - **page_size**: 每页数量（默认20，最大100）
    - **search**: 搜索关键词（设备编码、名称、位置）
    - **device_type**: 设备类型筛选
    - **status**: 设备状态筛选
    - **location**: 位置筛选
    - **materials_level_lt**: 耗材余量小于指定值
    - **sort_by**: 排序字段（默认updated_at）
    - **sort_order**: 排序方向（asc/desc，默认desc）
    """
    try:
        device_service = DeviceService(db)
        devices, total = device_service.get_device_list(query)
        
        # 转换为响应格式
        device_list = [DeviceResponse.from_orm(device).dict() for device in devices]
        
        return paginated_response(
            items=device_list,
            total=total,
            page=query.page,
            page_size=query.page_size,
            message="查询成功"
        )
        
    except Exception as e:
        logger.error(f"❌ 获取设备列表异常: {e}")
        return error_response(
            message="获取设备列表失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.get("/{device_id}", response_model=dict, summary="获取设备详情")
async def get_device_detail(
    device_id: int,
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    获取设备详细信息
    """
    try:
        device_service = DeviceService(db)
        detail_data = device_service.get_device_detail(device_id)
        
        device_detail = DeviceDetailResponse.from_orm(detail_data["device"])
        
        # 添加统计信息
        stats = detail_data["statistics"]
        device_detail.work_orders_count = stats.get("work_orders_count")
        device_detail.alerts_count = stats.get("alerts_count")
        device_detail.recent_sensor_data = stats.get("recent_sensor_data")
        
        return success_response(
            data=device_detail.dict(),
            message="查询成功"
        )
        
    except NotFoundException:
        return error_response(
            message="设备不存在",
            code=BusinessCode.DATA_NOT_FOUND
        )
    except Exception as e:
        logger.error(f"❌ 获取设备详情异常: {e}")
        return error_response(
            message="获取设备详情失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.put("/{device_id}", response_model=dict, summary="更新设备信息")
async def update_device(
    device_id: int,
    device_data: DeviceUpdate,
    current_user: dict = Depends(check_resource_permission(
        ResourcePermission.can_manage_devices, "无权限修改设备"
    )),
    db: Session = Depends(get_database)
):
    """
    更新设备信息（管理员和经理可操作）
    
    - **device_name**: 设备名称
    - **location_name**: 位置名称
    - **latitude**: 纬度
    - **longitude**: 经度
    - **firmware_version**: 固件版本
    - **hardware_version**: 硬件版本
    """
    try:
        device_service = DeviceService(db)
        device = device_service.update_device(device_id, device_data)
        
        logger.info(f"✅ 设备信息更新成功: {device.device_code} by {current_user['username']}")
        
        return success_response(
            data=DeviceResponse.from_orm(device).dict(),
            message="设备信息更新成功"
        )
        
    except NotFoundException:
        return error_response(
            message="设备不存在",
            code=BusinessCode.DATA_NOT_FOUND
        )
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except Exception as e:
        logger.error(f"❌ 更新设备信息异常: {e}")
        return error_response(
            message="更新设备信息失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.patch("/{device_id}/status", response_model=dict, summary="更新设备状态")
async def update_device_status(
    device_id: int,
    status_data: DeviceStatusUpdate,
    current_user: dict = Depends(check_resource_permission(
        ResourcePermission.can_control_devices, "无权限修改设备状态"
    )),
    db: Session = Depends(get_database)
):
    """
    更新设备状态（技术员及以上可操作）
    
    - **status**: 设备状态
    - **materials_level**: 耗材余量百分比（可选）
    """
    try:
        device_service = DeviceService(db)
        device = device_service.update_device_status(device_id, status_data)
        
        logger.info(f"✅ 设备状态更新: {device.device_code} -> {status_data.status} by {current_user['username']}")
        
        return success_response(
            data=DeviceResponse.from_orm(device).dict(),
            message="设备状态更新成功"
        )
        
    except NotFoundException:
        return error_response(
            message="设备不存在",
            code=BusinessCode.DATA_NOT_FOUND
        )
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except Exception as e:
        logger.error(f"❌ 更新设备状态异常: {e}")
        return error_response(
            message="更新设备状态失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.post("/{device_id}/control", response_model=dict, summary="控制设备")
async def control_device(
    device_id: int,
    control_data: DeviceControlRequest,
    current_user: dict = Depends(check_resource_permission(
        ResourcePermission.can_control_devices, "无权限控制设备"
    )),
    db: Session = Depends(get_database)
):
    """
    发送设备控制指令（技术员及以上可操作）
    
    - **commands**: 控制指令列表
    - **operator**: 操作员（可选）
    
    支持的控制指令：
    - door_control: 门锁控制 (unlock/lock)
    - light_control: 照明控制 (turn_on/turn_off, brightness)
    - ventilation_control: 通风控制 (turn_on/turn_off, speed)
    - maintenance_mode: 维护模式 (enable/disable, duration)
    """
    try:
        device_service = DeviceService(db)
        
        # 转换指令格式
        commands = [cmd.dict() for cmd in control_data.commands]
        operator = control_data.operator or current_user['username']
        
        success = await device_service.control_device(
            device_id=device_id,
            commands=commands,
            operator=operator
        )
        
        if success:
            logger.info(f"✅ 设备控制成功: 设备ID {device_id} by {current_user['username']}")
            return success_response(message="设备控制指令发送成功")
        else:
            return error_response(
                message="设备控制指令发送失败",
                code=BusinessCode.OPERATION_FAILED
            )
        
    except NotFoundException:
        return error_response(
            message="设备不存在",
            code=BusinessCode.DATA_NOT_FOUND
        )
    except BusinessException as e:
        return error_response(
            message=str(e),
            code=e.code
        )
    except Exception as e:
        logger.error(f"❌ 设备控制异常: {e}")
        return error_response(
            message="设备控制失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.get("/{device_id}/sensor-data", response_model=dict, summary="获取传感器数据")
async def get_sensor_data(
    device_id: int,
    data_type: str = Query(None, description="传感器类型"),
    start_time: str = Query(None, description="开始时间(ISO格式)"),
    end_time: str = Query(None, description="结束时间(ISO格式)"),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(100, ge=1, le=1000, description="每页数量"),
    current_user: dict = Depends(get_current_user),
    db: Session = Depends(get_database)
):
    """
    获取设备传感器数据
    
    - **device_id**: 设备ID
    - **data_type**: 传感器类型（可选）
    - **start_time**: 开始时间（可选）
    - **end_time**: 结束时间（可选）
    - **page**: 页码
    - **page_size**: 每页数量
    """
    try:
        from datetime import datetime
        
        # 解析时间参数
        start_dt = datetime.fromisoformat(start_time.replace('Z', '+00:00')) if start_time else None
        end_dt = datetime.fromisoformat(end_time.replace('Z', '+00:00')) if end_time else None
        
        query = SensorDataQuery(
            device_id=device_id,
            data_type=data_type,
            start_time=start_dt,
            end_time=end_dt,
            page=page,
            page_size=page_size
        )
        
        device_service = DeviceService(db)
        sensor_data, total = device_service.get_sensor_data(query)
        
        # 转换为响应格式
        data_list = [SensorDataResponse.from_orm(data).dict() for data in sensor_data]
        
        return paginated_response(
            items=data_list,
            total=total,
            page=page,
            page_size=page_size,
            message="查询成功"
        )
        
    except NotFoundException:
        return error_response(
            message="设备不存在",
            code=BusinessCode.DATA_NOT_FOUND
        )
    except Exception as e:
        logger.error(f"❌ 获取传感器数据异常: {e}")
        return error_response(
            message="获取传感器数据失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.post("/batch-operation", response_model=dict, summary="批量操作设备")
async def batch_operation(
    operation_data: DeviceBatchOperation,
    current_user: dict = Depends(check_resource_permission(
        ResourcePermission.can_manage_devices, "无权限批量操作设备"
    )),
    db: Session = Depends(get_database)
):
    """
    批量操作设备（管理员和经理可操作）
    
    - **device_ids**: 设备ID列表
    - **operation**: 操作类型 (update_status, delete)
    - **params**: 操作参数
    
    支持的批量操作：
    - update_status: 批量更新状态 (params: {status: "online/offline/fault/maintenance"})
    - delete: 批量删除设备
    """
    try:
        device_service = DeviceService(db)
        results = device_service.batch_operation(operation_data)
        
        logger.info(
            f"✅ 批量操作完成: {operation_data.operation}, "
            f"成功 {len(results['success'])}, 失败 {len(results['failed'])} "
            f"by {current_user['username']}"
        )
        
        return success_response(
            data=results,
            message=f"批量操作完成，成功 {len(results['success'])} 个，失败 {len(results['failed'])} 个"
        )
        
    except ValidationException as e:
        return error_response(
            message=str(e),
            code=BusinessCode.PARAM_ERROR
        )
    except Exception as e:
        logger.error(f"❌ 批量操作异常: {e}")
        return error_response(
            message="批量操作失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.delete("/{device_id}", response_model=dict, summary="删除设备")
async def delete_device(
    device_id: int,
    current_user: dict = Depends(check_resource_permission(
        ResourcePermission.can_manage_devices, "无权限删除设备"
    )),
    db: Session = Depends(get_database)
):
    """
    删除设备（管理员和经理可操作）
    
    注意：只能删除没有关联工单的设备
    """
    try:
        device_service = DeviceService(db)
        
        # 获取设备信息用于日志
        device = device_service.get_device_by_id(device_id)
        
        success = device_service.delete_device(device_id)
        
        if success:
            logger.info(f"✅ 设备删除成功: {device.device_code} by {current_user['username']}")
            return success_response(message="设备删除成功")
        else:
            return error_response(
                message="设备删除失败",
                code=BusinessCode.OPERATION_FAILED
            )
        
    except NotFoundException:
        return error_response(
            message="设备不存在",
            code=BusinessCode.DATA_NOT_FOUND
        )
    except BusinessException as e:
        return error_response(
            message=str(e),
            code=e.code
        )
    except Exception as e:
        logger.error(f"❌ 删除设备异常: {e}")
        return error_response(
            message="删除设备失败",
            code=BusinessCode.OPERATION_FAILED
        )


@router.get("/statistics/dashboard", response_model=dict, summary="获取设备仪表盘统计")
async def get_dashboard_statistics(
    current_user: dict = Depends(check_resource_permission(
        ResourcePermission.can_view_reports, "无权限查看统计报表"
    )),
    db: Session = Depends(get_database)
):
    """
    获取设备仪表盘统计数据（管理员和经理可查看）
    """
    try:
        device_service = DeviceService(db)
        stats = device_service.get_dashboard_statistics()
        
        return success_response(
            data=stats,
            message="查询成功"
        )
        
    except Exception as e:
        logger.error(f"❌ 获取仪表盘统计异常: {e}")
        return error_response(
            message="获取统计数据失败",
            code=BusinessCode.OPERATION_FAILED
        )